package com.boss.thirteen.service.impl;

import com.boss.common.entity.WfActionDTO;
import com.boss.common.enums.ActionTypeEnum;
import com.boss.framework.exception.AppRuntimeException;
import com.boss.salary.constant.SystemDictConstant;
import com.boss.salary.service.IRedisService;
import com.boss.sys.ca.user.dto.UserDTO;
import com.boss.sys.utils.SysUtils;
import com.boss.thirteen.dao.ISalaryThirteenMonthDao;
import com.boss.thirteen.dao.ISalaryThirteenMouldDao;
import com.boss.thirteen.dao.IThirteenAgencyVerifyDao;
import com.boss.thirteen.entity.SalaryThirteenMonth;
import com.boss.thirteen.entity.ThirteenAgencyVerify;
import com.boss.thirteen.service.ISalaryThirteenWorkFlowService;
import com.boss.thirteen.service.IThirteenMouldStartAsyncService;
import com.boss.thirteen.vo.ThirteenMouldVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ThirteenMouldStartAsyncServiceImpl implements IThirteenMouldStartAsyncService {

    @Autowired
    private ISalaryThirteenWorkFlowService iSalaryWorkFlowService;
    @Autowired
    private ISalaryThirteenMonthDao salaryThirteenMonthDao;
    @Autowired
    private ISalaryThirteenMouldDao salaryThirteenMouldDao;
    @Autowired
    private IThirteenAgencyVerifyDao thirteenAgencyVerifyDao;
    @Autowired
    private IRedisService redisService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void greateThitteenMonth(UserDTO userDTO, ThirteenMouldVO tv,String tokenid) {
        Object re=redisService.get(userDTO.getProvince()+"greateThitteenMonth");
        //查询缓存中该区划是否有在执行的生成操作
        if(!SysUtils.isNullOrEmpty(re)){
            throw new AppRuntimeException("模板启动中！请勿重复启动！");
        }
        List<SalaryThirteenMonth> stms=new ArrayList<>();
        List<String> agencyIds=new ArrayList<>();
        String year= String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
        List<Map<String, Object>> moulds=salaryThirteenMouldDao.selectSalaryThirteenMould(userDTO.getProvince(),year);
        if(CollectionUtils.isEmpty(moulds)){
            throw new AppRuntimeException("未找到模板无法开启！请先设计模板！");
        }
        if(SystemDictConstant.IS_SUBMIT.equals(moulds.get(0).get("is_workflow_start").toString())){
            throw new AppRuntimeException("模板已启动！请勿重复启动");
        }
        if(CollectionUtils.isEmpty(tv.getThirteenAgencyVerify())){
            throw new AppRuntimeException("模板未选单位无法开启！请修改模板！");
        }
        redisService.put(userDTO.getProvince()+"greateThitteenMonth",1);
        for(ThirteenAgencyVerify tav:tv.getThirteenAgencyVerify()){
            agencyIds.add(tav.getAgencyId());
            tav.setIsWorkflowInit(SystemDictConstant.IS_TRUE);
        }
        for(Map map:moulds){
           String salaryCodes= map.get("salary_codes").toString();
            List<String> columns =Arrays.asList(salaryCodes.split(","));
            Double percent=Double.parseDouble(map.get("percent").toString());
            stms.addAll(salaryThirteenMonthDao.selectSalaryThirteenMonthFromHistory(agencyIds,year+"-"+map.get("mould_month"),map.get("merit_pay_code").toString(),columns,percent));
        }

        try {
            for(SalaryThirteenMonth stm:stms){
                BigDecimal s1=new BigDecimal("0");
                for (int i=3;i<=100;i++) {
                    Class<?> clazz = stm.getClass();
                    Method getMethod = clazz.getDeclaredMethod("getS" +i);
                    String value=getMethod.invoke(stm)==null?"0":getMethod.invoke(stm).toString();
                    s1=s1.add(new BigDecimal(value));
                }
                s1=s1.multiply(new BigDecimal(stm.getPercent())).setScale(2,BigDecimal.ROUND_HALF_UP);;
                stm.setS1(s1.doubleValue());
            }
            salaryThirteenMonthDao.deleteSalaryThirteenBeginByProvince(userDTO.getProvince());//清除之前begin表数据
            salaryThirteenMonthDao.batchInsertSalaryThirteenMonth(stms);//编报表数据插入
            salaryThirteenMonthDao.batchInsertSalaryThirteenBegin(stms);//初始表数据插入
        } catch (NoSuchMethodException e) {
            redisService.del(userDTO.getProvince()+"greateThitteenMonth");
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            redisService.del(userDTO.getProvince()+"greateThitteenMonth");
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            redisService.del(userDTO.getProvince()+"greateThitteenMonth");
            e.printStackTrace();
        }
        WfActionDTO<List<ThirteenAgencyVerify>> wfActionDTO = new WfActionDTO();
        wfActionDTO.setMenuguid(tv.getMenuid());
        // 录入并审核
        wfActionDTO.setActionType(ActionTypeEnum.WF_INPUT_AUDIT.getActionTypeCode());
        wfActionDTO.setBizDatas(tv.getThirteenAgencyVerify());
        wfActionDTO.setBizKeyName("bizKey");
        salaryThirteenMouldDao.updateSalaryThirteenMouldStatus(moulds.get(0).get("biz_key").toString(), SystemDictConstant.NOT_END,SystemDictConstant.IS_SUBMIT);
        thirteenAgencyVerifyDao.batchUpdateThirteenAgencyVerify(tv.getThirteenAgencyVerify());
        iSalaryWorkFlowService.doSalaryFlowList(userDTO,wfActionDTO,null,tokenid);
        redisService.del(userDTO.getProvince()+"greateThitteenMonth");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revokeThirteenMould(UserDTO userDTO){
        Map<String, Object> params=new HashMap<>();
        String year= String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
        List<Map<String, Object>> moulds=salaryThirteenMouldDao.selectSalaryThirteenMould(userDTO.getProvince(),year);
        params.put("mof_div_code",userDTO.getProvince());
        params.put("year",year);
        List<ThirteenAgencyVerify> tvs =thirteenAgencyVerifyDao.selectThirteenAgencyVerify(params);
        List<ThirteenAgencyVerify> isPay=tvs.stream().filter(tv->tv.getIsPayDataCreated()==1).collect(Collectors.toList());
        if(!SysUtils.isNullOrEmpty(isPay)){
            throw new AppRuntimeException("存在已生成支付单位！无法撤销流程！");
        }
        List<String> bizkeys=tvs.stream().map(ThirteenAgencyVerify::getBizKey).collect(Collectors.toList());
        WfActionDTO<String> wfActionDTO = new WfActionDTO();
        wfActionDTO.setBizDatas(bizkeys.stream().map(String::valueOf).collect(Collectors.joining(",")));
//        iSalaryWorkFlowService.terminations(userDTO,wfActionDTO);//作废工作流
        List<String> agencyIds=tvs.stream().map(ThirteenAgencyVerify::getAgencyId).collect(Collectors.toList());
        salaryThirteenMonthDao.deleteSalaryThirteenMonthByAgency(agencyIds);
        salaryThirteenMonthDao.deleteSalaryThirteenBeginByAgency(agencyIds,year);
        salaryThirteenMouldDao.updateSalaryThirteenMouldStatus(moulds.get(0).get("biz_key").toString(), SystemDictConstant.NOT_END,SystemDictConstant.NO_SUBMIT);
        for(ThirteenAgencyVerify tv:tvs){
            tv.setBizKey(SysUtils.generateGuid());
            tv.setIsWorkflowInit(SystemDictConstant.IS_FALSE);
        }
        thirteenAgencyVerifyDao.batchUpdateThirteenAgencyVerify(tvs);
    }

}
